package com.yunlan.materia.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yunlan.materia.entity.PatientInfo;
import com.yunlan.materia.enums.BaseStatusEnum;
import com.yunlan.materia.enums.BusinessEnum;
import com.yunlan.materia.enums.DeleteEnum;
import com.yunlan.materia.exceptions.GlobalException;
import com.yunlan.materia.mapper.PatientInfoMapper;
import com.yunlan.materia.request.DeletePatientInfoRequest;
import com.yunlan.materia.request.PatientInfoRequest;
import com.yunlan.materia.request.QueryPatientRequest;
import com.yunlan.materia.response.PatientInfoResponse;
import com.yunlan.materia.service.PatientInfoService;
import com.yunlan.materia.utils.IdCardUtil;
import com.yunlan.materia.utils.ObjectEmptyChecker;
import com.yunlan.materia.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;

/**
 * @author 罗显
 * @date 2025/9/18
 * @ApiNote
 */
@Slf4j
@Service
public class PatientInfoServiceImpl implements PatientInfoService {

    @Resource
    PatientInfoMapper patientInfoMapper;

    @Override
    public PatientInfoResponse createPatientRecord(PatientInfoRequest request) {
        PatientInfo patientInfo = queryByPhoneOrIdCard(request.getContactPhone(), request.getIdCard());
        if (patientInfo != null){
            throw new GlobalException(BusinessEnum.DATA_EXIST.getCode(),BusinessEnum.DATA_EXIST.getMsg());
        }
        PatientInfo entity = new PatientInfo();
        BeanCopier beanCopier = BeanCopier.create(PatientInfoRequest.class, PatientInfo.class,false);
        beanCopier.copy(request,entity,null);
        Map<String, String> idCardMap = IdCardUtil.getCarInfo(request.getIdCard());
        entity.setUniqueCode(StringUtils.generatorUniqueCodeByType("patient"));
        entity.setGender(idCardMap.get("gender"));
        entity.setAge(Integer.valueOf(idCardMap.get("age")));
        LocalDateTime now = LocalDateTime.now();
        entity.setCreateTime(now);
        entity.setUpdateTime(now);
        entity.setOperatingTime(now);
        entity.setDelete(DeleteEnum.NORMAL.getCode());
        entity.setPatientStatus(BaseStatusEnum.NORMAL.getCode());
        patientInfoMapper.insert(entity);

        return convertResponse(request.getContactPhone(),request.getIdCard());
    }

    @Override
    public int deletePatientInfo(DeletePatientInfoRequest request) {
        return 0;
    }

    @Override
    public PatientInfoResponse queryPatientInfo(QueryPatientRequest request) {
        if (ObjectEmptyChecker.isAllFieldsNull(request)){
          throw new GlobalException(BusinessEnum.PARAMS_IS_NULL.getCode(),BusinessEnum.PARAMS_IS_NULL.getMsg());
        }

        PatientInfo patientInfo = patientInfoMapper.selectOne(new LambdaQueryWrapper<PatientInfo>()
                .eq(StringUtils.isNotBlank(request.getId() + ""), PatientInfo::getId, request.getId())
                .eq(StringUtils.isNotBlank(request.getUniqueCode()), PatientInfo::getUniqueCode, request.getUniqueCode())
                .eq(StringUtils.isNotBlank(request.getUserName()), PatientInfo::getUserName, request.getUserName())
                .eq(StringUtils.isNotBlank(request.getContactPhone()), PatientInfo::getContactPhone, request.getContactPhone())
                .eq(StringUtils.isNotBlank(request.getIdCard()), PatientInfo::getIdCard, request.getIdCard()));
        if (Objects.isNull(patientInfo)){
            return null;
        }

        PatientInfoResponse response = new PatientInfoResponse();
        BeanCopier beanCopier = BeanCopier.create(PatientInfo.class, PatientInfoResponse.class,false);
        beanCopier.copy(patientInfo,response,null);
        return response;
    }

    @Override
    public List<PatientInfoResponse> queryPatientInfos(QueryPatientRequest request) {
        List<PatientInfo> patientInfos = patientInfoMapper.selectList(new LambdaQueryWrapper<PatientInfo>()
                .eq(StringUtils.isNotBlank(request.getId() + ""), PatientInfo::getId, request.getId())
                .eq(StringUtils.isNotBlank(request.getUniqueCode()), PatientInfo::getUniqueCode, request.getUniqueCode())
                .like(StringUtils.isNotBlank(request.getUserName()), PatientInfo::getUserName, request.getUserName())
                .like(StringUtils.isNotBlank(request.getContactPhone()), PatientInfo::getContactPhone, request.getContactPhone())
                .like(StringUtils.isNotBlank(request.getIdCard()), PatientInfo::getIdCard, request.getIdCard()));
        if (CollectionUtils.isEmpty(patientInfos)){
            return Collections.emptyList();
        }
        List<PatientInfoResponse> result = new ArrayList<>();
        for (PatientInfo patientInfo : patientInfos) {
            PatientInfoResponse response = new PatientInfoResponse();
            BeanCopier beanCopier = BeanCopier.create(PatientInfo.class, PatientInfoResponse.class,false);
            beanCopier.copy(patientInfo,response,null);
            patientInfo.setIdCard(IdCardUtil.maskIdCard(patientInfo.getIdCard()));
            patientInfo.setContactPhone(IdCardUtil.maskMobile(patientInfo.getContactPhone(),3,4,'*'));
            result.add(response);
        }
        return result;
    }

    @Override
    public Map<String, Object> queryPatientDetails(QueryPatientRequest request) {
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("patientInfo",queryPatientInfos(request));


        return resultMap;
    }

    @Override
    public PatientInfo queryByPhoneOrIdCard(String phone, String idCard) {
        if (StringUtils.isBlank(phone) && StringUtils.isBlank(idCard)){
            throw new GlobalException(BusinessEnum.PARAMS_IS_NULL.getCode(),BusinessEnum.PARAMS_IS_NULL.getMsg());
        }
        return patientInfoMapper.selectOne(new LambdaQueryWrapper<PatientInfo>()
                .eq(StringUtils.isNotBlank(phone), PatientInfo::getContactPhone, phone)
                .eq(StringUtils.isNotBlank(idCard), PatientInfo::getIdCard, idCard));
    }

    private PatientInfoResponse convertResponse(String phone,String idCard){
        PatientInfo queryByPhoneOrIdCard = queryByPhoneOrIdCard(phone,idCard);
        if (Objects.isNull(queryByPhoneOrIdCard)){
            return null;
        }
        PatientInfoResponse response = new PatientInfoResponse();
        BeanCopier beanCopier = BeanCopier.create(PatientInfo.class, PatientInfoResponse.class,false);
        beanCopier.copy(response,queryByPhoneOrIdCard,null);
        return response;
    }
}
